package com.advertisementsystem.utils;


import jakarta.servlet.http.HttpServletRequest;
import org.springframework.util.StringUtils;


public class IpUtils {

    // IP地址的正则表达式
    private static final String IP_PATTERN = "^(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\."
            + "(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."
            + "(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."
            + "(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)$";

    /**
     * 判断是否为内网IP
     *
     * 内网IP范围：
     * A类：10.0.0.0 - 10.255.255.255
     * B类：172.16.0.0 - 172.31.255.255
     * C类：192.168.0.0 - 192.168.255.255
     */
    public static boolean internalIp(String ip) {
        if (StringUtils.isEmpty(ip) || !ip.matches(IP_PATTERN)) {
            return false;
        }

        try {
            byte[] addr = textToNumericFormatV4(ip);
            if (addr == null || addr.length != 4) {
                return false;
            }

            // 判断是否为本地回环地址 127.0.0.1
            final byte b0 = addr[0];
            if (b0 == 127) {
                return true;
            }

            final byte b1 = addr[1];
            switch (b0) {
                case 10: // A类内网
                    return true;
                case (byte) 172: // B类内网
                    return b1 >= 16 && b1 <= 31;
                case (byte) 192: // C类内网
                    return false;
                default:
                    return false;
            }
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 将IPv4地址转换成字节数组
     */
    public static byte[] textToNumericFormatV4(String text) {
        if (text.length() == 0) {
            return null;
        }

        byte[] bytes = new byte[4];
        String[] elements = text.split("\\.", -1);
        try {
            long l;
            int i;
            if (elements.length == 4) {
                for (i = 0; i < 4; ++i) {
                    l = Long.parseLong(elements[i]);
                    if (l < 0L || l > 255L) {
                        return null;
                    }
                    bytes[i] = (byte) ((int) (l & 255L));
                }
                return bytes;
            }
        } catch (NumberFormatException e) {
            return null;
        }
        return null;
    }

    /**
     * 获取IP地址
     */
    public static String getIpAddr(HttpServletRequest request) {
        if (request == null) {
            return "unknown";
        }

        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("X-Forwarded-For");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("X-Real-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }

        // 多个代理的情况，第一个IP为客户端真实IP
        if (ip != null && ip.indexOf(",") != -1) {
            ip = ip.substring(0, ip.indexOf(",")).trim();
        }

        return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : ip;
    }
}